package com.xyh.builder;

import com.xyh.bean.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.StandardCharsets;

/**
 * 构建目标项目所需的pom.xml配置文件
 */
public class BuildEnv {
    private static final Logger logger = LoggerFactory.getLogger(BuildEnv.class);

    public static void execute() {
        File pomFile = new File(Constants.PATH_ROOT, "pom.xml");

        try (BufferedWriter bw = new BufferedWriter(
                new OutputStreamWriter(new FileOutputStream(pomFile), StandardCharsets.UTF_8))) {

            // 写入XML头部和项目基本信息
            writePomHeader(bw);

            // 写入properties配置
            writeProperties(bw);

            // 写入依赖管理
            writeDependencyManagement(bw);

            // 写入dependencies
            writeDependencies(bw);

            // 写入build配置
            writeBuildConfig(bw);

            bw.write("</project>");
            bw.flush();

            logger.info("生成pom.xml成功: {}", pomFile.getAbsolutePath());
        } catch (Exception e) {
            logger.error("生成pom.xml失败", e);
        }
    }

    private static void writePomHeader(BufferedWriter bw) throws IOException {
        bw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        bw.write("<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n");
        bw.write("         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
        bw.write("         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd\">\n");
        bw.write("    <modelVersion>4.0.0</modelVersion>\n\n");

        bw.write("    <!-- 项目基本信息 -->\n");
        bw.write("    <groupId>"+Constants.PROJECT_GROUP_ID+"</groupId>\n");
        bw.write("    <artifactId>"+Constants.PROJECT_NAME+"</artifactId>\n");
        bw.write("    <version>"+Constants.PROJECT_VERSION+"</version>\n");
        bw.write("    <name>"+Constants.PROJECT_NAME+"</name>\n");
        bw.write("    <description>"+Constants.PROJECT_DESCRIPTION+"</description>\n\n");
    }

    private static void writeProperties(BufferedWriter bw) throws IOException {
        bw.write("    <!-- 项目属性配置 -->\n");
        bw.write("    <properties>\n");
        bw.write("        <java.version>17</java.version>\n");
        bw.write("        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n");
        bw.write("        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>\n\n");

        bw.write("        <!-- 依赖版本控制 -->\n");
        bw.write("        <spring-boot.version>3.1.5</spring-boot.version>\n");
        bw.write("        <mybatis-plus.version>3.5.5</mybatis-plus.version>\n");
        bw.write("        <mysql-connector.version>8.0.33</mysql-connector.version>\n");
        bw.write("        <lombok.version>1.18.30</lombok.version>\n");
        bw.write("        <fastjson.version>2.0.34</fastjson.version>\n");
        bw.write("        <hibernate-validator.version>8.0.1.Final</hibernate-validator.version>\n");
        bw.write("    </properties>\n\n");
    }

    private static void writeDependencyManagement(BufferedWriter bw) throws IOException {
        bw.write("    <!-- 依赖管理 -->\n");
        bw.write("    <dependencyManagement>\n");
        bw.write("        <dependencies>\n");
        bw.write("            <dependency>\n");
        bw.write("                <groupId>org.springframework.boot</groupId>\n");
        bw.write("                <artifactId>spring-boot-dependencies</artifactId>\n");
        bw.write("                <version>${spring-boot.version}</version>\n");
        bw.write("                <type>pom</type>\n");
        bw.write("                <scope>import</scope>\n");
        bw.write("            </dependency>\n");
        bw.write("        </dependencies>\n");
        bw.write("    </dependencyManagement>\n\n");
    }

    private static void writeDependencies(BufferedWriter bw) throws IOException {
        bw.write("    <!-- 项目依赖 -->\n");
        bw.write("    <dependencies>\n");

        // Spring Boot 基础依赖
        writeDependency(bw, "org.springframework.boot", "spring-boot-starter-web", null);
        writeDependency(bw, "org.springframework.boot", "spring-boot-starter-data-redis", null);

        // 持久层
        writeDependency(bw, "com.baomidou", "mybatis-plus-boot-starter", "${mybatis-plus.version}");
        writeDependency(bw, "com.mysql", "mysql-connector-j", "${mysql-connector.version}");

        // 开发工具
        writeDependency(bw, "org.springframework.boot", "spring-boot-devtools", null, "runtime", true);
        writeDependency(bw, "org.projectlombok", "lombok", "${lombok.version}", null, true);

        // 工具库
        writeDependency(bw, "com.alibaba.fastjson2", "fastjson2", "${fastjson.version}");
        writeDependency(bw, "org.apache.commons", "commons-lang3", "3.14.0");
        //验证码
        writeDependency(bw, "com.github.penggle", "kaptcha", "2.3.2");

        // 安全校验
        writeDependency(bw, "jakarta.validation", "jakarta.validation-api", null);
        writeDependency(bw, "org.hibernate.validator", "hibernate-validator", "${hibernate-validator.version}");

        // 测试
        writeDependency(bw, "org.springframework.boot", "spring-boot-starter-test", null, "test", false);

        bw.write("    </dependencies>\n\n");
    }

    private static void writeDependency(BufferedWriter bw, String groupId, String artifactId, String version) throws IOException {
        writeDependency(bw, groupId, artifactId, version, null, false);
    }

    private static void writeDependency(BufferedWriter bw, String groupId, String artifactId, String version,
                                        String scope, boolean optional) throws IOException {
        bw.write("        <dependency>\n");
        bw.write("            <groupId>" + groupId + "</groupId>\n");
        bw.write("            <artifactId>" + artifactId + "</artifactId>\n");
        if (version != null) {
            bw.write("            <version>" + version + "</version>\n");
        }
        if (scope != null) {
            bw.write("            <scope>" + scope + "</scope>\n");
        }
        if (optional) {
            bw.write("            <optional>true</optional>\n");
        }
        bw.write("        </dependency>\n");
    }

    private static void writeBuildConfig(BufferedWriter bw) throws IOException {
        bw.write("    <!-- 构建配置 -->\n");
        bw.write("    <build>\n");
        bw.write("        <plugins>\n");

        // Maven编译器插件
        bw.write("            <plugin>\n");
        bw.write("                <groupId>org.apache.maven.plugins</groupId>\n");
        bw.write("                <artifactId>maven-compiler-plugin</artifactId>\n");
        bw.write("                <version>3.11.0</version>\n");
        bw.write("                <configuration>\n");
        bw.write("                    <source>${java.version}</source>\n");
        bw.write("                    <target>${java.version}</target>\n");
        bw.write("                    <encoding>UTF-8</encoding>\n");
        bw.write("                    <annotationProcessorPaths>\n");
        bw.write("                        <path>\n");
        bw.write("                            <groupId>org.projectlombok</groupId>\n");
        bw.write("                            <artifactId>lombok</artifactId>\n");
        bw.write("                            <version>${lombok.version}</version>\n");
        bw.write("                        </path>\n");
        bw.write("                    </annotationProcessorPaths>\n");
        bw.write("                </configuration>\n");
        bw.write("            </plugin>\n\n");

        // Spring Boot Maven插件
        bw.write("            <plugin>\n");
        bw.write("                <groupId>org.springframework.boot</groupId>\n");
        bw.write("                <artifactId>spring-boot-maven-plugin</artifactId>\n");
        bw.write("                <version>${spring-boot.version}</version>\n");
        bw.write("                <configuration>\n");
        bw.write("                    <excludes>\n");
        bw.write("                        <exclude>\n");
        bw.write("                            <groupId>org.projectlombok</groupId>\n");
        bw.write("                            <artifactId>lombok</artifactId>\n");
        bw.write("                        </exclude>\n");
        bw.write("                    </excludes>\n");
        bw.write("                </configuration>\n");
        bw.write("            </plugin>\n");

        bw.write("        </plugins>\n");
        bw.write("    </build>\n");
    }
}